package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectDemo1 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
		/*获取Person类的Class对象的三种方式：
		 * 1.类名.class属性
		 * 2.对象.getClass()方法获取
		 * 3. Class.forName("reflect.Person")  
		 */
		//1.类名.class属性
		Class clazz1=Person.class;
		//2.对象.getClass()方法获取
		Person p=new Person("wang",43);
		Class  clazz2=p.getClass();
		//3. Class.forName("reflect.Person")
		Class clazz3=Class.forName("reflect.Person");
		Constructor[]c=clazz1.getDeclaredConstructors();//获取所有构造方法
		for (Constructor con:c) {
			System.out.println(con);
		}
		//获取Person类中private的构造
		Constructor c1=clazz1.getDeclaredConstructor();
		//强制访问私有的构造方法
		c1.setAccessible(true);//获取访问权限
		Object o=c1.newInstance();
		Person p1=(Person)o;
		p1.setAge(33);
		p1.setName("song");
		System.out.println(p1);
       Field d =clazz1.getDeclaredField("name");//获取成员变量
       d.setAccessible(true);
       d.set(o, "tang");
       System.out.println(o);
       Method m = clazz1.getDeclaredMethod("show", String.class,int.class);//获取方法
       m.setAccessible(true);
       m.invoke(o, "hi",88);
       Method m1=  clazz1.getDeclaredMethod("display");
       m1.invoke(o);
       setProperty(o, "name", "libingbing");
       getProperty(o,"name");
	}
	/*4.写一个方法，此方法可将obj对象中名为propertyName的属性的值设置为value
	public static void setProperty(Object obj, String propertyName, Object value){}*/
		public static void setProperty(Object obj, String propertyName, Object value) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException{
			Class clazz=obj.getClass();
			Field f=clazz.getDeclaredField(propertyName);
			f.setAccessible(true);
			f.set(obj, value);
			System.out.println(obj);
		
     }
	//5.1.写一个方法，此方法可以获取obj对象中名为propertyName的属性的值
		public static void getProperty(Object obj,String propertyName) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
			Class clazz=obj.getClass();
			Field f=clazz.getDeclaredField(propertyName);
			f.setAccessible(true);
			System.out.println(f.get(obj));
		}
		
}